package com.aitao.util;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 类型转换器
 *
 * @Company QAX
 * @Author : ai.tao
 * @Create : 2022/3/18 17:29
 */
public class Converter {
    /**
     * 将集合转换成Map结构
     *
     * @param collection 集合
     * @param <V>        集合元素类型
     * @return {@link Map<Integer, V>}
     */
    public static <V> Map<Integer, V> toMap(Collection<V> collection) {
        Map<Integer, V> retMap = new HashMap<>();
        int count = 0;
        for (V value : collection) {
            retMap.put(count++, value);
        }
        return retMap;
    }

    /**
     * 将任意对象转换成Map结构
     *
     * @param obj 对象
     * @return {@link Map<String, Object>}
     */
    public static Map<String, Object> toMap(Object obj) {
        Map<String, Object> map = new LinkedHashMap<>();
        if (obj != null) {
            //获取当前对象的类
            Class<?> clazz = obj.getClass();
            List<String> ignoreField = Arrays.asList("serialVersionUID", "LOGGER");
            //获取该类所有的字段信息
            Field[] fields = getFields(clazz);
            if (fields != null) {
                for (Field field : fields) {
                    //忽略serialVersionUID 和 logger
                    if (ignoreField.contains(field.getName())) {
                        continue;
                    }
                    field.setAccessible(true);
                    try {
                        map.put(field.getName(), field.get(obj));
                    } catch (Exception e) {
                        throw new RuntimeException("获取对象数据异常");
                    }
                }
            }
        }
        return map;
    }


    /**
     * 获取指定类对象中的所有字段
     *
     * @param clazz 类对象
     * @return 返回字段集合
     */
    public static Field[] getFields(Class<?> clazz) {
        if (clazz == Object.class) { // 获取父类
            return null;
        }
        // 获取父类字段
        return combineFields(getFields(clazz.getSuperclass()), clazz.getDeclaredFields());
    }

    /**
     * 合并2个Filed数组
     *
     * @param f1 字段数组1
     * @param f2 字段数组2
     * @return 返回合并后的字段集合
     */
    public static Field[] combineFields(Field[] f1, Field[] f2) {
        if (f1 == null && f2 == null) {
            return null;
        } else if (f2 == null) {
            return f1;
        } else if (f1 == null) {
            return f2;
        }
        int length = f1.length + f2.length;
        Field[] fields = new Field[length];
        int i = 0;
        for (Field field : f1) {
            fields[i++] = field;
        }
        for (Field field : f2) {
            fields[i++] = field;
        }
        return fields;
    }
}
